﻿namespace Serializator.JSONObjects
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    /// <summary>
    /// Wrapper class
    /// </summary>
    public abstract class JSONObject : IEnumerable, IDisposable
    {
        #region Finalizer

        ~JSONObject()
        {
            Dispose(false);
        }

        #endregion

        #region Properties

        /// <summary>
        /// Get serialized data
        /// </summary>
        public abstract string EncodedStream();

        public string Stream
        {
            set
            {
                m_Stream = value;
            }
        }

        public List<JSONObject> EncodedStreamList
        {
            get { return m_list; }
            set { m_list = value; }
        }

        #endregion

        #region IEnumerable Implementation

        public IEnumerator GetEnumerator()
        {
            return (IEnumerator)new ListIterator(this.m_list);
        }

        #endregion

        #region IDisposable Implementation

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool managedDispose)
        {
            if (m_dispose)
                return;

            if (managedDispose)
            {
                ///TODO: release managed resources
            }

            m_list.Clear();
            m_Stream = string.Empty;

            m_dispose = true;
        }

        #endregion

        #region Fields

        protected string m_Stream = string.Empty;
        protected List<JSONObject> m_list = new List<JSONObject>();
        private bool m_dispose = false;

        #endregion

        #region Enumerator Class

        private class ListIterator : IEnumerator
        {
            public ListIterator(List<JSONObject> list)
            {
                m_list = list;
            }

            public bool MoveNext()
            {
                m_position++;
                return (m_position < m_list.Count);
            }

            public void Reset()
            {
                m_position = -1;
            }

            object IEnumerator.Current
            {
                get
                {
                    try
                    {
                        return m_list[m_position];
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new IndexOutOfRangeException();
                    }
                }
            }

            #region Private Fields

            private List<JSONObject> m_list;
            private int m_position = -1;

            #endregion
        }

        #endregion
    }
}
